Odtwarzanie sampli na C64

Data

Mimo, iż powstały dziesiątki artykułów o tej tematyce, zdecydowałem się napisać swój. Być może dlatego, że dla muzyka na C64 puszczającego oko w kierunku sampli jest to jak podróż do Mekki dla muzułmanina, a być może dlatego, że jest to nadal rozwijająca się dziedzina wiedzy o C64 wymagająca popularyzacji swoich aktualności. Ten artykuł będzie o odtwarzaniu sampli, więc lecimy od podstaw. Jeśli jesteś koderem lub muzykiem, po prostu przeskocz poniższy akapit.

Tak, jak ryby żyją w oceanie wody, tak my żyjemy w oceanie mieszanki gazów nazywanej powietrzem. Wszelkie zmiany ciśnienia w swoim środowisku ryby odczuwają dzięki swoim uszom i linii bocznej, my natomiast dzięki naszym uszom i skórze. Ponieważ ocean jest znacznie gęstszym środowiskiem od powietrza na lądzie, ryby słyszą znacznie niższy zakres częstotliwości do ok. 2 KHz, podczas gdy człowiek do ok. 20 KHz. Włączenie swojego zestawu audio oznacza dynamiczną zmianę ciśnienia powietrza w swoim pokoju. Ponieważ powietrze wypełnia wszelkie zakamarki naszego ciała i naciska nieustannie na nasze bębenki słuchowe ze średnią siłą 1013 hPa (powietrze waży całkiem sporo od ziemi do termosfery licząc), każda zmiana w tym nacisku pobudza nasz mózg elektrycznie poprzez młoteczek, kowadełko, strzemiączko, ślimak i nerwy. Aby wygenerować falę akustyczną z naszych głośników, należy odwrócić ten proces. Membrana głośnikowa zmienia ciśnienie powietrza, poruszana jest przez cewkę w magnesie napięciem elektrycznym (indukcja) pochodzącym z naszego wzmacniacza, które jest dynamicznie modulowane przez nasz C64.

Ponieważ wchodzimy do C64 od strony wyjścia audio, należałoby napisać o najstarszej metodzie odtwarzania sampli, która mimo swoich wad nadal jest czasem stosowana. Układ SID ma na swoim wyjściu 4-bitowy rejestr głośności $D418, którym możemy zmieniać amplitudę (modulować) wszystko to, co zostało wcześniej wygenerowane w układzie SID. Tak, jak w powyższym analogowym przykładzie, powietrze jest nośną, a dźwięk tylko zmianą jego ciśnienia (drganiem), tak w przypadku SID, metoda z $D418 działa ponieważ rejestr ten zmienia poziom napięcia DC wyjścia audio. W C64 jest on dosyć zróżnicowany w zależności od tego, czy posiadamy układ 6581, czy 8580 i o ile mnie pamięć nie myli mieści się w granicach 2-3V. $D418 daje możliwość podniesienia tego poziomu w zakresie 16 poziomów. Metoda ta ma w moim mniemaniu jedną wielką zaletę i dwie poważne wady. Zaletą jest jej prostota. Wadą jest fakt, iż daje tylko 4-bitową dynamikę i nie umożliwia miksowania sampli z innymi dźwiękami z układu, gdyż oba wpływają na siebie wzajemnie. Kiedyś istniała jeszcze jedna wada tego podejścia. Nowe układy 8580 zostały pozbawione wad 6581 i poziom szumów został znacznie obniżony, co wpłynęło na niższy poziom DC i przez to sample odtwarzane na nowych SID starą metodą były bardzo ciche. Przez lata pojawiły się zarówno rozwiązania sprzętowe, jaki programowe eliminujące ten problem nad którymi nie będziemy się tutaj rozwodzić.

Odtworzenie próbki 4-bit zawartej w młodszym półbajcie wygląda następująco:

LDA sample AND #$0f STA $D418

Odtworzenie próbki 4-bit zawartej w starszym półbajcie wygląda następująco:

LDA sample LSR LSR LSR LSR STA $D418

Kolejną interesującą metodą odtwarzania sampli jest PWM. Aby wyjaśnić na jakiej zasadzie działa, posłużę się przykładem z życia wziętym. W demie Digital World/Samar można zaobserwować, jak dioda napędu dyskietek podczas trwania dema sympatycznie pulsuje. Sensei/Arise programując swój loader nie miał możliwości wpłynięcia na poziom napięcia na tej diodzie. Mógł ją tylko programowo włączyć lub wyłączyć. PWM to metoda polegająca na modulacji częstotliwościowej, czyli stosunku częstotliwości włączeń do wyłączeń. Jeżeli czas w którym dioda pozostaje włączona jest dłuższy niż czas w którym jest wyłączona, wizualnie odbieramy to jako jaśniejsze świecenie (pomijając diabelne mrużenie). Czyli bez kontroli nad amplitudą (jasnością) wpłynęliśmy na nią poprzez częstotliwość. Tej samej techniki używają elektronarzędzia, ściemniacze do świateł, podświetlanie matryc LCD, zasilacze impulsowe i wiele innych ciekawych rzeczy. W przypadku układu SID mamy generator przebiegu prostokątnego, który możemy włączyć na maksymalną częstotliwość 4 KHz. Na częstotliwość włączeń i wyłączeń wpływamy za pomocą 12-bitowego rejestru PWM, który wydłuża dla nas czas trwania impulsu. Te dwanaście bitów brzmi elektryzująco, jednak w technikach PWM częstotliwość jest handlowana za dynamikę, co oznacza w praktyce, że fala prostokątna w oscylatorach SID-a jest zbyt powolna, aby odwzorowywać próbki o wysokiej dynamice i częstotliwości. Można oczywiście pominąć wsparcie sprzętowe i wygenerować przebieg prostokątny wyższej częstotliwości przez CPU oraz użyć więcej kanałów SID. Najlepsze efekty na tym polu uzyskał H rsfalvi Levente dając nam w 2001 roku software’owe PWM wykorzystujące bit testowy układu SID, dzięki któremu można było odtwarzać 7,5-bitowe sample z częstotliwością ok. 15 KHz. Dlaczego więc nigdy nie zobaczyliśmy wysypu dem wykorzystujących tę technikę? Niestety nawet to koderskie mistrzostwo pożerało cały czas procesora, wszystkie kanały SID-a i w dalszym ciągu w sygnale pozostawała nośna słyszana jako świdrujący w uszach pisk towarzyszący odtwarzanym samplom. Była jednak postępem w porównaniu do metody $D418. Dawała o niebo wyższą dynamikę, dodatkowo możliwość nakładania filtrów, czy sterowania obwiednią, gdyż te znajdują się za oscylatorami odtwarzającymi sample.
Odtworzenie trzech próbek 8-bit na trzech kanałach metodą Lavente po inicjalizacji rejestrów SID:

LDA sample1 ;(sample do niższego bajtu rejestru PWM) STA $D402 LDA #$49 ;(oscylator włączony, bit testowy włączony, fala prostokątna włączona) STA $D404 LDA #$41 ;(oscylator włączony, bit testowy wyłączony, fala prostokątna włączona) STA $D404 LDA sample2 STA $D409 LDA #$49 STA $D40B LDA #$41 STA $D40B LDA sample3 STA $D410 LDA #$49 STA $D412 LDA #$41 STA $D412

Jednakże zmaganiom Lavente przyglądał się inny młody badacz układu SID zainteresowany programowaniem minimalistycznych playerów zaków do intr 4K. Otto Jarvinen znany jako SounDemoN/Dekadence mniej więcej w roku 2005 zmienił świat sampli na C64 mimo, że uważał je za wyjątkowo nudne. Dzięki jego metodzie odtwarzania nastała nowa era dla C64 w dziedzinie dźwięku. Poważnie… Nie bylibyśmy na tym poziomie produkcji demoscenowych, gdyby nie to odkrycie sprzed 10 lat. Nowa metoda w porównaniu do PWM dała nam pełne 8-bit (a nawet 12-bit), nie świszczy w uszach, nie zajmuje wszystkich oscylatorów, a jej apetyt na czas procesora jest bliższy metodzie $D418 niż PWM. Zbyt piękne, aby mogło być prawdziwe? Dodajmy jeszcze, że tak, jak PWM, umożliwia nakładanie efektów obwiedni i filtrów. Jak więc działa? Oscylatory układu SID są w istocie akumulatorami fazy, a konkretniej 24-bitowymi rejestrami z układami dodającymi, które zwiększają wartość tych rejestrów o 1 z każdym tyknięciem zegara C64. Kiedy włączamy przebieg piłokształtny i uruchamiamy oscylator, akumulator fazy zwiększa swoją wartość do max, po czym się zeruje i rozpoczyna od nowa. Stąd uzyskujemy falę o kształcie zębów piły. Dzięki 16-bitowemu rejestrowi częstotliwości, którego wartość jest również dodawana do akumulatora fazy w każdym cyklu zegarowym, możemy wpływać na prędkość narastania fali, czyli w efekcie jej częstotliwość. Do tego krajobrazu dodajmy jeszcze bit testowy. Jego włączenie powoduje wyzerowanie akumulatora fazy. Jest to bardzo istotne, gdyż nasze sample będziemy ładować właśnie do rejestru częstotliwości. Kluczowym jest więc, aby akumulator fazy przed dodaniem naszej próbki zawierał tą samą wartość. Całość sprowadza się więc do uruchomienia oscylatora z falą piłokształtną lub trójkątną, następnie zresetowanie akumulatora fazy bitem testowym, załadowanie go naszą próbką i uruchomienie oscylatora ponownie z wyłączoną falą. W teorii ta procedura nie powinna działać, jednakże SounDemoN odkrył, iż wyłączenie fali nie skutkuje wcale nagłym spadkiem poziomu DC na wyjściu audio, jak powszechnie sądzono. Poziom ten spada samoczynnie do zera w ciągu kilku sekund, a relatywnie stały poziom DC na wyjściu audio programowalny od wewnątrz to dokładnie to, czego potrzebujemy do odtwarzania sampli.
Odtworzenie jednej próbki 8-bit na pierwszym oscylatorze po inicjalizacji rejestrów SID:

LDA #$11 ;(oscylator włączony, fala trójkątna włączona) STA $D404 LDA #$09 ;(oscylator włączony, bit testowy włączony, fala wyłączona) STA $D404 LDA sample ;(próbka 8-bit ładowana do wyższego bajta rejestru częstotliwości) STA $D401 LDA #$01 ;(oscylator włączony, bit testowy wyłączony, fala wyłączona) STA $D404

Jeśli po przeczytaniu powyższego akapitu dostrzegłeś pewną nieścisłość pomiędzy tym 16-bitowym rejestrem częstotliwości a stanowiskiem, iż metoda SounDemoNa umożliwia odtwarzanie nawet 12-bitowych sampli, spieszę z wyjaśnieniem. Otóż można owszem ładować próbki 16-bit, jednakże efektywnie uzyskamy dynamikę co najwyżej 12-bit ze względu na to, że taka jest rozdzielczość przetwornika DAC w układzie SID. Jeśli ta informacja Cię zasmuciła, to prawdopodobnie wymagasz od C64 zbyt wiele. Bardziej dotkliwym ograniczeniem powyższej metody jest fakt, iż wymaga pełnej synchronizacji z rastrem. Dzieje się tak dlatego, że oscylatory SID działają niezależnie od procesora i w odróżnieniu od niego nie są zatrzymywane przez VIC-II. Dlatego, jeśli na przykład powyższa procedura uruchomi falę, ale zostanie zatrzymana na kilkadziesiąt cykli w wyniku krótkiej linii rastra, akumulator fazy nie będzie czekał i gdy procesor znów dostanie dostęp do magistrali, wartość próbki w akumulatorze będzie zupełnie inna niż powinna. Na szczęście SounDemoN zaproponował też bardziej złożoną wersję procedury, która działa przy niestabilnym rastrze, choć pochłania drugi oscylator SID (odsyłam do artykułu na codebase64). Można też zsynchronizować swój kod tak, aby powyższy jego kawałek nie trafiał w krótką linię.

Warto wspomnieć o jeszcze jednej cesze tej metody, której istnienie uzmysłowiłem sobie pisząc swój player pod REU. Mianowicie procedura słabo sprawdza się przy ekstremalnie szybkich playerach. Powodem jest fakt, że próbka powstaje poprzez dodanie wartości rejestru częstotliwości do akumulatora fazy. Fala jednak może narastać nawet przez 256 cykli, a im wyższa jest, tym wyższy będzie poziom DC na wyjściu. Dlatego prędkości odtwarzania wynoszące kilkadziesiąt KHz choć możliwe, będą mało przydatne.

Data/Tropyx